package br.com.fogas.impressora;

import java.util.ArrayList;

import br.com.fogas.utils.StringUtility;

import rego.PrintLib.mobilePrinter;

public class ImpressoraMPT_Builder {

	private mobilePrinter printer;
	
	public ImpressoraMPT_Builder() throws ImpressoraMPTException {
		this.printer = new mobilePrinter();
		
	}
	
	public ImpressoraMPT_Builder conectar() throws ImpressoraMPTException{
		//if (printer == null || printer.LnitLib() == false) 
		//	throw new ImpressoraMPTException();
		
		boolean bRes = printer.LnitLib();
		if(!bRes) {
        	throw new ImpressoraMPTException();
        }
		
		ArrayList<String> printerlist = printer.GetBondedDevices();
   	 
		boolean conexaoImpressora = false;
		int index = 0;
		
		for (String deviceName : printerlist) {
			if(deviceName.contains("MPT")){
				conexaoImpressora = printer.ConnectDevice(printerlist, index);
				break;
	   		}
			index++;
		}
		
		if(!conexaoImpressora) {
			throw new ImpressoraMPTException("impressora nao conectada");
		}
		
		return this;
	}
	
	public ImpressoraMPT_Builder fecharConexao() throws ImpressoraMPTException{
		try{			
			printer.CloseConnect();
			printer.FreeLib(true);
			return this;
		}
		catch(Exception e){
			throw new ImpressoraMPTException("erro ao fechar conexao impressora");
		}
	}
	
	public enum ALIGN{
		AL_LEFT(0), AL_RIGHT(2), AL_CENTER(1);
		private int value;
		
		private ALIGN(int value){
			this.value = value;
		}
	}
	
	public ImpressoraMPT_Builder imprimirLinha(String line) throws ImpressoraMPTException {
		return imprimirLinha(line, 1, false, false, false, ALIGN.AL_LEFT);		
	}
	
	public ImpressoraMPT_Builder imprimirLinhaBranco() throws ImpressoraMPTException {
		imprimirLinha("");
		return this;
	}
	
	public ImpressoraMPT_Builder imprimirLinha(String line, boolean bold) throws ImpressoraMPTException {
		return imprimirLinha(line, 1, bold, false, false, ALIGN.AL_LEFT);		
	}
	
	public ImpressoraMPT_Builder imprimirLinha(String line, ALIGN align) throws ImpressoraMPTException {
		return imprimirLinha(line, 1, false, false, false, align);		
	}
	
	public ImpressoraMPT_Builder imprimirLinha(String line, int feed) throws ImpressoraMPTException {
		return imprimirLinha(line, feed, false, false, false, ALIGN.AL_LEFT);		
	}
			 
	public ImpressoraMPT_Builder imprimirLinha(String line, int feed,
			boolean bold, boolean under, boolean mini, ALIGN align)
			throws ImpressoraMPTException {
		try {
			if(printer.QueryPrinterStatus() == mobilePrinter.PS_NORMAL){
				line = StringUtility.stripAccents(line);
				line = StringUtility.upperCase(line);
				printer.Reset();	
				printer.AlignType(align.value);				
				printer.FormatString(false, false, bold, under, mini);
				printer.SendString(line);
				printer.FeedLines(feed);
				return this;
			} else {
				throw new ImpressoraMPTException("erro ao imprimir a linha");
			}
		}catch(Exception e){
			throw new ImpressoraMPTException("erro ao imprimir a linha");
		}
	}
	
	private byte[] logo00 = new byte[] { (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0 };
	private byte[] logo01 = new byte[] { (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 3, (byte) 128, (byte) 0, (byte) 15, (byte) 224,
			(byte) 0, (byte) 31, (byte) 240, (byte) 0, (byte) 63, (byte) 248,
			(byte) 0, (byte) 127, (byte) 252, (byte) 0, (byte) 255, (byte) 254,
			(byte) 7, (byte) 255, (byte) 240 };
	private byte[] logo02 = new byte[] { (byte) 31, (byte) 255, (byte) 224,
			(byte) 15, (byte) 255, (byte) 192, (byte) 7, (byte) 255,
			(byte) 128, (byte) 1, (byte) 254, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 1, (byte) 0, (byte) 0, (byte) 1, (byte) 0, (byte) 0,
			(byte) 3, (byte) 0, (byte) 0, (byte) 3, (byte) 0, (byte) 0,
			(byte) 7, (byte) 0, (byte) 0, (byte) 7, (byte) 0, (byte) 0,
			(byte) 15, (byte) 0, (byte) 0, (byte) 15 };
	private byte[] logo03 = new byte[] { (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0 };
	private byte[] logo04 = new byte[] { (byte) 0, (byte) 0, (byte) 0,
			(byte) 127, (byte) 255, (byte) 248, (byte) 127, (byte) 255,
			(byte) 248, (byte) 127, (byte) 255, (byte) 248, (byte) 127,
			(byte) 255, (byte) 248, (byte) 127, (byte) 255, (byte) 248,
			(byte) 127, (byte) 255, (byte) 248, (byte) 127, (byte) 254,
			(byte) 248, (byte) 124, (byte) 124, (byte) 0, (byte) 124,
			(byte) 124, (byte) 0, (byte) 124, (byte) 124, (byte) 0, (byte) 124,
			(byte) 124, (byte) 0, (byte) 124, (byte) 124, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 120, (byte) 0, (byte) 3,
			(byte) 255, (byte) 0, (byte) 15, (byte) 255, (byte) 192, (byte) 31,
			(byte) 255, (byte) 224, (byte) 63, (byte) 255, (byte) 240,
			(byte) 63, (byte) 255, (byte) 240, (byte) 127, (byte) 135,
			(byte) 248, (byte) 126, (byte) 3, (byte) 248, (byte) 126, (byte) 1,
			(byte) 248, (byte) 252, (byte) 0, (byte) 248 };
	private byte[] logo05 = new byte[] { (byte) 252, (byte) 0, (byte) 252,
			(byte) 252, (byte) 0, (byte) 252, (byte) 126, (byte) 1, (byte) 248,
			(byte) 126, (byte) 3, (byte) 248, (byte) 127, (byte) 135,
			(byte) 248, (byte) 63, (byte) 255, (byte) 240, (byte) 63,
			(byte) 255, (byte) 240, (byte) 31, (byte) 255, (byte) 224,
			(byte) 15, (byte) 255, (byte) 192, (byte) 3, (byte) 255, (byte) 0,
			(byte) 0, (byte) 252, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 0, (byte) 3, (byte) 255, (byte) 0,
			(byte) 15, (byte) 255, (byte) 128, (byte) 31, (byte) 255,
			(byte) 192, (byte) 63, (byte) 255, (byte) 224, (byte) 127,
			(byte) 255, (byte) 240, (byte) 127, (byte) 223, (byte) 248,
			(byte) 126, (byte) 3, (byte) 248, (byte) 252, (byte) 1, (byte) 248,
			(byte) 252, (byte) 1, (byte) 248, (byte) 252, (byte) 120,
			(byte) 252, (byte) 252, (byte) 120, (byte) 252 };
	private byte[] logo06 = new byte[] { (byte) 252, (byte) 121, (byte) 248,
			(byte) 126, (byte) 121, (byte) 248, (byte) 126, (byte) 127,
			(byte) 248, (byte) 124, (byte) 127, (byte) 248, (byte) 60,
			(byte) 127, (byte) 240, (byte) 28, (byte) 127, (byte) 224,
			(byte) 12, (byte) 127, (byte) 192, (byte) 0, (byte) 127,
			(byte) 128, (byte) 0, (byte) 126, (byte) 8, (byte) 0, (byte) 0,
			(byte) 120, (byte) 0, (byte) 7, (byte) 248, (byte) 0, (byte) 63,
			(byte) 248, (byte) 1, (byte) 255, (byte) 248, (byte) 31,
			(byte) 255, (byte) 248, (byte) 255, (byte) 255, (byte) 248,
			(byte) 255, (byte) 255, (byte) 248, (byte) 255, (byte) 255,
			(byte) 192, (byte) 255, (byte) 243, (byte) 192, (byte) 255,
			(byte) 3, (byte) 192, (byte) 255, (byte) 131, (byte) 192,
			(byte) 255, (byte) 243, (byte) 192, (byte) 255, (byte) 255,
			(byte) 192, (byte) 255, (byte) 255, (byte) 248, (byte) 63,
			(byte) 255, (byte) 248 };
	private byte[] logo07 = new byte[] { (byte) 15, (byte) 255, (byte) 248,
			(byte) 1, (byte) 255, (byte) 248, (byte) 0, (byte) 63, (byte) 248,
			(byte) 0, (byte) 7, (byte) 248, (byte) 0, (byte) 0, (byte) 248,
			(byte) 0, (byte) 0, (byte) 24, (byte) 0, (byte) 0, (byte) 0,
			(byte) 0, (byte) 0, (byte) 112, (byte) 31, (byte) 227, (byte) 240,
			(byte) 63, (byte) 243, (byte) 248, (byte) 127, (byte) 241,
			(byte) 248, (byte) 127, (byte) 248, (byte) 248, (byte) 255,
			(byte) 248, (byte) 248, (byte) 255, (byte) 248, (byte) 248,
			(byte) 255, (byte) 252, (byte) 252, (byte) 249, (byte) 254,
			(byte) 248, (byte) 248, (byte) 255, (byte) 248, (byte) 252,
			(byte) 255, (byte) 248, (byte) 252, (byte) 255, (byte) 248,
			(byte) 252, (byte) 127, (byte) 240, (byte) 124, (byte) 127,
			(byte) 240, (byte) 96, (byte) 63, (byte) 224, (byte) 0, (byte) 31,
			(byte) 128, (byte) 0, (byte) 0, (byte) 0 };

	public ImpressoraMPT_Builder imprimirLogo() throws ImpressoraMPTException{
		try{
			byte[] Byte = new byte[] { 27, 42, 33, 24, 0 };
			
			printer.Reset();
			printer.AlignType(ALIGN.AL_LEFT.value);
			
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo00, logo00.length);
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo01, logo01.length);
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo02, logo02.length);
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo03, logo03.length);
			endLine();
			
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo04, logo04.length);
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo05, logo05.length);
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo06, logo06.length);
			printer.SendBuffer(Byte,   Byte.length);
			printer.SendBuffer(logo07, logo07.length);
			endLine();
			
			printer.SendString("");
			
			return this;
		}
		catch(Exception e){
			throw new ImpressoraMPTException("erro ao imprimir logo");
		}
	}
	
	private void endLine(){
		byte[] Byte = new byte[1];
        Byte[0] = 10;
        printer.SendBuffer(Byte, Byte.length);
	}
	
	public ImpressoraMPT_Builder imprimirCodigoBarras(String codigo) throws ImpressoraMPTException{
		
		try{
			byte[] configuration = new byte[]{ 29, 104, 64,     // altura do codigo de barras
					                           29, 119, 02,     // largura do codigo de barras
					                           29, 72 , 00,     // HRI: nao mostrar numeros 
					                           29, 107, 73, 24, // comprimento do codigo
					                           123, 67 };       // padrao 128 tipo C 
			
			byte[] code = new byte[] { Byte.valueOf(codigo.substring(0, 2)),
					Byte.valueOf(codigo.substring(2, 4)),
					Byte.valueOf(codigo.substring(4, 6)),
					Byte.valueOf(codigo.substring(6, 8)),
					Byte.valueOf(codigo.substring(8, 10)),
					Byte.valueOf(codigo.substring(10, 12)),
					Byte.valueOf(codigo.substring(12, 14)),
					Byte.valueOf(codigo.substring(14, 16)),
					Byte.valueOf(codigo.substring(16, 18)),
					Byte.valueOf(codigo.substring(18, 20)),
					Byte.valueOf(codigo.substring(20, 22)),
					Byte.valueOf(codigo.substring(22, 24)),
					Byte.valueOf(codigo.substring(24, 26)),
					Byte.valueOf(codigo.substring(26, 28)),
					Byte.valueOf(codigo.substring(28, 30)),
					Byte.valueOf(codigo.substring(30, 32)),
					Byte.valueOf(codigo.substring(32, 34)),
					Byte.valueOf(codigo.substring(34, 36)),
					Byte.valueOf(codigo.substring(36, 38)),
					Byte.valueOf(codigo.substring(38, 40)),
					Byte.valueOf(codigo.substring(40, 42)),
					Byte.valueOf(codigo.substring(42, 44)) };
			
			
			printer.Reset();				
			printer.SendBuffer(configuration, configuration.length);
			printer.SendBuffer(code, code.length);
			printer.Reset();

			return this;
		}
		catch(Exception e){
			throw new ImpressoraMPTException("erro ao imprimir codigo barras");
		}
	}
	
	public ImpressoraMPT_Builder sendBytes(byte[] Bytes){
		printer.Reset();
		printer.SendBuffer(Bytes, Bytes.length);
		return this;
	}
	
	public ImpressoraMPT_Builder sendByte(byte Byte){
		byte[] aByte = new byte[1];
		aByte[0] = Byte;
		
		printer.SendBuffer(aByte, aByte.length);
		return this;
	}
}